/* Copyright 2012 Oliver Katz

    This file is part of Theta.

    Theta is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */

#ifndef __THETA_DATA_H
#define __THETA_DATA_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdio.h>
#include <string.h>
#include <malloc.h>

typedef enum
{
	// Null-Allocated pun:
	N0,
	// Stack-Allocated variables:
	S8,
	S16,
	S32,
	S64,
	// Heap-Alloacted variables for optimization:
	H8,
	H16,
	H32,
	// Stack-Only compound variables:
	SC
} t_data_meta_type;

typedef struct
{
	t_data_meta_type type;
	void *data;
} t_data_meta;

t_data_meta t_data_meta_init();
t_data_meta t_data_meta_init_with_type(t_data_meta_type t);
t_data_meta t_data_meta_init_with_type_value(t_data_meta_type t, long v);
t_data_meta t_data_meta_init_compound(int n, t_data_meta *t);
t_data_meta_type t_data_meta_get_type(t_data_meta *m);
int t_data_meta_compound_get_size(t_data_meta *m);
t_data_meta t_data_meta_compound_get(t_data_meta *m, int n);
void *t_data_meta_get_value(t_data_meta *m);
void t_data_meta_del(t_data_meta *m);

#define T_DATA_META_PAGE_INITSIZE 64
#define T_DATA_META_PAGE_INCSIZE 32

typedef struct
{
	t_data_meta *root;
	t_data_meta *head;
	int size;
} t_data_meta_page;

t_data_meta_page t_data_meta_page_init();
int t_data_meta_page_put_dirty(t_data_meta_page *p, t_data_meta m);
int t_data_meta_page_put_clean(t_data_meta_page *p, t_data_meta m);
t_data_meta t_data_meta_page_get(t_data_meta_page *p, int addr);
void t_data_meta_page_rem(t_data_meta_page *p, int addr);
void t_data_meta_page_del(t_data_meta_page *p);

#ifdef __cplusplus
}
#endif

#endif